package com.ruoyi.odorservice.service;

import com.ruoyi.odorservice.config.MinIOProperties;
import com.ruoyi.odorservice.utils.ViewContentType;
import io.minio.*;
import io.minio.http.Method;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;

import java.io.InputStream;

@Slf4j
@Component
@EnableConfigurationProperties({MinIOProperties.class})
public class MinIOService implements InitializingBean {

    private MinIOProperties minIOProperties;

    public MinIOService(MinIOProperties minIOProperties){
        this.minIOProperties=minIOProperties;
    }

    private MinioClient client;

    @Override
    public void afterPropertiesSet() {
        this.client = new MinioClient.Builder()
                .endpoint(minIOProperties.getEndpoint())
                .credentials(minIOProperties.getAccessKey(), minIOProperties.getSecretKey())
                .build();
    }

    @SneakyThrows
    public void createBucketIfAbsent(String bucketName) {
        BucketExistsArgs bucketExistsArgs = BucketExistsArgs.builder()
                .bucket(bucketName)
                .build();
        if (!client.bucketExists(bucketExistsArgs)) {
            MakeBucketArgs makeBucketArgs = MakeBucketArgs.builder()
                    .bucket(bucketName).build();
            client.makeBucket(makeBucketArgs);
            setBucketPolicy(bucketName);
        }
    }

    public String putObject(String bucketName, String objectName, InputStream inputStream) {
        try {
            createBucketIfAbsent(bucketName);
            setBucketPolicy(bucketName);
            String policy = client.getBucketPolicy(GetBucketPolicyArgs.builder().bucket(bucketName).build());
            log.info("client.getBucketPolicy start");
            log.info(policy);
            log.info("client.getBucketPolicy end");
            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .contentType(ViewContentType.getContentType(objectName))
                    .stream(inputStream, inputStream.available(), -1)
                    .build();
            client.putObject(putObjectArgs);
            // 查看文件地址
            GetPresignedObjectUrlArgs build = GetPresignedObjectUrlArgs.builder().bucket(bucketName)
                    .object(objectName).method(Method.GET).build();
            String path = client.getPresignedObjectUrl(build);
            int index = path.indexOf("?");
            if (index > 0){
                log.info(path.substring(0,index));
                return path.substring(0,index);
            }else{
                log.info(path);
                return path;
            }
        }catch (Exception e){
            log.error("文件上传失败！");
        }
        return null;
    }

    public void removeObject(String bucketName, String objectName) throws Exception {
        RemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder()
                .bucket(bucketName)
                .object(objectName)
                .build();
        client.removeObject(removeObjectArgs);
    }

    public InputStream getObject(String bucketName, String objectName) throws Exception {
        GetObjectArgs getObjectArgs = GetObjectArgs.builder()
                .bucket(bucketName)
                .object(objectName)
                .build();
        return client.getObject(getObjectArgs);
    }

    public void setBucketPolicy(String bucketName){
        try {
            String s = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucket\",\"s3:ListBucketMultipartUploads\"],\"Resource\":[\"arn:aws:s3:::"+bucketName+"\"]},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:AbortMultipartUpload\",\"s3:DeleteObject\",\"s3:GetObject\",\"s3:ListMultipartUploadParts\",\"s3:PutObject\"],\"Resource\":[\"arn:aws:s3:::"+bucketName+"/*\"]}]}";
            client.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(bucketName).config(s).build());
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
